package com.hrt.datasender.datacollect.drive.ttmb;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.btcode.schedule.ScheduleManager;
import com.hrt.datasender.datacollect.drive.DriveBase;
import com.hrt.datasender.datacollect.drive.DriveConfigModel;
import com.hrt.datasender.datacollect.drive.DriveParameterMetadata;
import com.hrt.datasender.datadao.model.BcDevicesModel;
import com.hrt.datasender.datadao.model.BdSourceModel;
import com.hrt.datasender.mq.MqKit;
import com.hrt.datasender.mq.MqKit.MsgListener;
import com.hrt.datasender.mq.model.MqModel;
import com.hrt.datasender.mq.model.SerialModel;

/**
 * 2018年1月22日
 * 此类继承DriveBase，注册串口数据询问定时器，并实现监听消息队列中的串口消息，其中解析数据的方法processSerialData，留给子类实现
 * 
 * @author gislin
 *
 */
public abstract class TTMBSerialBaseDrive extends DriveBase {

    /**
     * 注册消息监听，调用子类的getSourceDataFromDevice方法解析数据
     */
    protected void registerMQListener(BcDevicesModel device, HashMap<Integer, String> paramCodeMap,
            DriveConfigModel configs) {

        MqKit.consumeMsgFromSerialMQ(device, new MsgListener() {

            @Override
            public void onReceive(MqModel mqModel) {

                SerialModel model = (SerialModel) mqModel;
                List<BdSourceModel> datas = processSerialData(model.getData(), paramCodeMap, configs);
                log.info("数据解析成功，size:" + datas.size());
                setSourceData(datas);
            }
        });
    }

    /**
     * 注册数据询问定时任务，这里使用 {@link TTMBSerialDataAsker} 作为定时器 <br>
     * 定时器不能通过构造函数传参，只能通过构造HashMap<String, Object>的方式进行传参
     */
    protected void registerAskDataJob(BcDevicesModel device, DriveConfigModel configs) {
        HashMap<String, Object> data = new HashMap<>();

        data.put("device", device);
        data.put("deviceConfigs", configs);

        String jobName = getClass().getName() + "." + device.getId();

        ScheduleManager.getInstance().addJob(TTMBSerialDataAsker.class, getConsStr(), data, jobName);
    }

    /**
     * 从设备中获取原始数据
     * 
     * @return
     */
    public abstract List<BdSourceModel> processSerialData(byte[] data, HashMap<Integer, String> paramCodeMap,
            DriveConfigModel configs);

    @Override
    public List<DriveParameterMetadata> getParameterMetadata() {

        List<DriveParameterMetadata> params = new ArrayList<>();
        params.add(new DriveParameterMetadata("slaveNo", "从站编号"));
        // params.add(new DriveParameterMetadata("startNo","数据读取位置"));
        // params.add(new
        // DriveParameterMetadata("dataLength","数据读取长度(如果是32位，数据长度要x2)"));
        return params;
    }
}
